﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using GCC.APIContainer.Utilities;
using GCC.Container.Abstracts;
using GCC.Container.Models;

using Microsoft.AspNetCore.Mvc;

using tcm.entity;
using tcm.entity.System;
using tcm.Filters;
using tcm.request.System;
using tcm.utils;

namespace tcm.Controller.SystemManage
{
    [ApiController]//记住这个单词
    [Route("tcm/sysmenu")]//记住这个
    public class SysMenuController : GCCAPIControllerBase
    {
        private readonly AbsGCCContext _context;
        public SysMenuController(AbsGCCContext context) : base(context)
        {
            _context = context;
        }

        /// <summary>
        /// 查询菜单列表
        /// </summary>
        /// <returns></returns>
        [HttpGet("getlist")]
        public DataResponse<List<SysMenu>> GetList([FromQuery] SysMenuRequest request)
        {
            var list = new List<SysMenu>();
            var roleMenuIds = new List<long>();
            long count = 0;
            
            var user = GetUserInfo(HttpContext.GetToken());
            if (user==null)
                return HandleData(list, count);

            //获取用户角色菜单列表，如果是管理员则为空
            roleMenuIds=GetMenuIds(user.user_id);

            list = GCCEntrance.DBManager!.LocalDB!.Select<SysMenu>()
                .WhereIf(roleMenuIds!=null&& roleMenuIds.Count>0, item => roleMenuIds.Contains(item.id))
                .WhereIf(!string.IsNullOrWhiteSpace(request.menu_name), item => item.menu_name.Contains(request.menu_name!))
                .WhereIf(request.menu_type.HasValue, item => item.menu_type==request.menu_type.Value!)
                .WhereIf(request.status.HasValue, item => item.menu_status==request.status.Value!)
                .Count(out count)
                .OrderBy(item => item.menu_sort)
                .ToList();


            return HandleData(list, count);
        }


        /// <summary> 
        /// 查询菜单详情
        /// </summary>
        /// <returns></returns>
        [HttpGet("get/{id}")] 
        public DataResponse<SysMenu> GetSysMenu([FromRoute] long id)
        {
            var res = GCCEntrance.DBManager!.LocalDB!.Queryable<SysMenu>().Where(x => x.id==id).First();
            return HandleData(res);
        }


        /// <summary>
        /// 获取菜单下拉树列表(分配角色所需菜单)
        /// </summary>
        /// <returns></returns>
        [HttpGet("treeSelect")]
        public DataResponse<List<SysMenu>> TreeSelect()
        {
            List<SysMenu> menuTrees = new List<SysMenu>();
            //var treeMenuVos = new List<TreeSelectVo>();
            var user = GetUserInfo(HttpContext.GetToken());
            if (user==null)
                return HandleData(new List<SysMenu>()); ;

            //获取用户角色菜单列表，如果是管理员则为空
            var roleMenuIds = GetMenuIds(user.user_id);

            if ((roleMenuIds ==null || roleMenuIds.Count==0)&&!user.isAdmin)
            {
                return HandleData(menuTrees);
            }
            var menus = GCCEntrance.DBManager!.LocalDB!.Select<SysMenu>()
             .WhereIf(roleMenuIds!=null&& roleMenuIds.Count>0, item => roleMenuIds.Contains(item.id))
             .Where(x => x.menu_status==1)
             .OrderBy(x => x.menu_sort)
             .ToList();

            //递归拼装树形结构
            menuTrees = BuildMenuTree(menus);

            
            //foreach (var item in menuTrees)
            //{
            //    treeMenuVos.Add(new TreeSelectVo(item));
            //}

            return HandleData(menuTrees);
        }



        /// <summary>
        /// 添加菜单
        /// </summary>
        /// <returns></returns>
        [HttpPost("add")]
        [TCMAuth(permission: "system:menu:add")]
        public DataResponse<bool> AddSysMenu([FromBody] SysMenuDto request)
        {
            var saveRes = false;

            if (GCCEntrance.DBManager!.LocalDB!.Queryable<SysMenu>().Where(x => x.menu_name==request.menu_name).Any())
            {
                return SystemError<bool>("菜单名称已存在");
            };
            GCCEntrance.DBManager!.LocalDB!.Transaction(() =>
            {
                _=request.Create(_context, HttpContext.GetToken());
                var info = BeanUtils.copy<SysMenu, SysMenuDto>(request);
                info.id=request.id;
                info.parent_id=request.parent_id;
                info.menu_name=request.menu_name;
                info.menu_icon=request.menu_icon;
                info.menu_url=request.menu_url;
                info.menu_sort=request.menu_sort;
                info.menu_type=request.menu_type;
                info.component=request.component;
                info.menu_status=request.menu_status;
                info.authorize=request.authorize;
                info.remark=request.remark;
                info.create_date=request.create_date;
                info.create_by=request.create_by;
                info.update_by=request.update_by;
                info.update_date =request.update_date;

                if (GCCEntrance.DBManager!.LocalDB!.Insert(info).ExecuteAffrows() != 1)
                {
                    throw new Exception();
                }
                saveRes=true;
            });

            return HandleData(saveRes);
        }



        /// <summary>
        /// 修改菜单
        /// </summary>
        /// <returns></returns>
        [HttpPost("update")]
        public DataResponse<bool> UpdateSysMenu([FromBody] SysMenuDto request)
        {
            var saveRes = false;
            if (request.id<=0)
                return SystemError<bool>("id为空");

            if (GCCEntrance.DBManager!.LocalDB!.Queryable<SysMenu>().Where(x => x.menu_name==request.menu_name&& x.id != request.id).Any())
            {
                return SystemError<bool>("菜单名称已存在");
            };

            GCCEntrance.DBManager!.LocalDB!.Transaction(() =>
            {
                _=request.Modify(_context, HttpContext.GetToken());
                saveRes = GCCEntrance.DBManager!.LocalDB!.Update<SysMenu>(request.id)
                .Set(item => item.parent_id, request.parent_id)
                .Set(item => item.menu_name, request.menu_name)
                .Set(item => item.menu_icon, request.menu_icon)
                .Set(item=>item.component,request.component)
                .Set(item => item.menu_url, request.menu_url)
                .Set(item => item.menu_sort, request.menu_sort)
                .Set(item => item.menu_type, request.menu_type)
                .Set(item => item.menu_status, request.menu_status)
                .Set(item => item.authorize, request.authorize)
                .Set(item => item.remark, request.remark)
                .Set(item => item.update_by, request.update_by)
                .Set(item => item.update_date, request.update_date)
                .ExecuteAffrows()==1;

            });

            return HandleData(saveRes);
        }


        /// <summary>
        /// 删除菜单
        /// </summary>
        /// <returns></returns>
        [HttpDelete("delete/{id}")]
        [TCMAuth(permission: "system:menu:remove")]
        public DataResponse<bool> DeleteSysMenu([FromRoute] long id)
        {
            var saveRes = false;
            if (id<=0)
                return SystemError<bool>("id为空");

            var menus = GCCEntrance.DBManager!.LocalDB!.Select<SysMenu>().Where(x => x.parent_id ==id).ToList();
            if (menus !=null && menus.Count>0)
            {
                return SystemError<bool>("存在子菜单,不允许删除");
            }

            var roleMenus = GCCEntrance.DBManager!.LocalDB!.Select<SysRoleMenu>().Where(x => x.menu_id ==id).ToList();
            if (roleMenus !=null && roleMenus.Count>0)
            {
                return SystemError<bool>("菜单已分配,不允许删除");
            }

            saveRes = GCCEntrance.DBManager!.LocalDB!.Delete<SysMenu>().Where(x => id==x.id).ExecuteAffrows()>0;

            return HandleData(saveRes);
        }


        /// <summary>
        /// 获取用户信息
        /// </summary>
        /// <param name="role_id"></param>
        /// <param name="menuIds"></param>
        private LoginUser GetUserInfo(string token)
        {
            return AuthManager.GetUserInfoByToken(_context, token);
        }



        /// <summary>
        /// 获取用户角色菜单列表，如果是管理员则为空
        /// </summary>
        /// <param name="role_id"></param>
        /// <param name="menuIds"></param>
        private static List<long> GetMenuIds(long user_id)
        {

            var roles = GCCEntrance.DBManager!.LocalDB!.Select<SysRole, SysUserRole>().Where((r, ur) => r.id==ur.role_id && ur.user_id==user_id && r.is_delete==0 && r.status==1)
            .ToList();

            var roleKeys = roles?.Select(x => x.role_key).ToList();
            var isAdmin = roleKeys!=null && roleKeys.Contains("admin");

            //如果不是管理员根据角色查询
            if (!isAdmin)
            {
                var roleIds = roles?.Select(x => x.id).ToList();

                var roleMenus = GCCEntrance.DBManager!.LocalDB!.Select<SysRoleMenu>().Where(x => roleIds.Contains(x.role_id)).ToList();
                return roleMenus?.Select(m => m.menu_id).ToList();
            }
            return null;
        }

        /// <summary>
        /// 构建前端所需要下拉树结构
        /// </summary>
        /// <param name="menus">菜单列表</param>
        /// <returns>下拉树结构列表</returns>
        private static List<SysMenu> BuildMenuTree(List<SysMenu> menus)
        {
            List<SysMenu> returnList = new List<SysMenu>();
            List<long> tempList = menus.Select(f => f.id).ToList();

            foreach (var menu in menus)
            {
                // 如果是顶级节点, 遍历该父节点的所有子节点
                if (!tempList.Contains(menu.parent_id??0))
                {
                    RecursionFn(menus, menu);
                    returnList.Add(menu);
                }
            }
            if (!returnList.Any())
            {
                returnList = menus;
            }
            return returnList;
        }

        /// <summary>
        /// 递归列表
        /// </summary>
        /// <param name="list"></param>
        /// <param name="t"></param>
        private static void RecursionFn(List<SysMenu> list, SysMenu t)
        {
            //得到子节点列表
            List<SysMenu> childList = GetChildList(list, t);
            t.children = childList;
            foreach (var item in childList)
            {
                if (GetChildList(list, item).Count() > 0)
                {
                    RecursionFn(list, item);
                }
            }
        }

        /// <summary>
        /// 递归获取子菜单
        /// </summary>
        /// <param name="list">所有菜单</param>
        /// <param name="sysMenu"></param>
        /// <returns></returns>
        private static List<SysMenu> GetChildList(List<SysMenu> list, SysMenu sysMenu)
        {
            return list.Where(p => p.parent_id == sysMenu.id).ToList();
        }


        ///// <summary>
        ///// 获取用户角色key
        ///// </summary>
        ///// <param name="role_id"></param>
        ///// <param name="menuIds"></param>
        //private static bool IsAdmin(long? user_id)
        //{
        //    if (!user_id.HasValue || user_id.Value<=0)
        //        return false;

        //    var roles = GCCEntrance.DBManager!.LocalDB!.Select<SysRole, SysUserRole>().Where((r, ur) => r.id==ur.role_id && ur.user_id==user_id.Value && r.is_delete==0 && r.status==1)
        //      .ToList();

        //    var roleKeys = roles?.Select(x => x.role_key).ToList();
        //    return roleKeys!=null && roleKeys.Contains("admin");
        //}



        ///// <summary>
        ///// 获取用户角色id
        ///// </summary>
        ///// <param name="role_id"></param>
        ///// <param name="menuIds"></param>
        //private static List<long> GetRoleId(long? user_id)
        //{
        //    if (!user_id.HasValue || user_id.Value<=0)
        //        return null;

        //    var roles = GCCEntrance.DBManager!.LocalDB!.Select<SysRole, SysUserRole>().Where((r, ur) => r.id==ur.role_id && ur.user_id==user_id.Value && r.is_delete==0 && r.status==1)
        //      .ToList();

        //    var roleKeys = roles?.Select(x => x.id).ToList();


        //}












    }
}
